package u.can.i.up.gexf;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import it.uniroma1.dis.wsngroup.gexf4j.core.EdgeType;
import it.uniroma1.dis.wsngroup.gexf4j.core.Gexf;
import it.uniroma1.dis.wsngroup.gexf4j.core.Graph;
import it.uniroma1.dis.wsngroup.gexf4j.core.Mode;
import it.uniroma1.dis.wsngroup.gexf4j.core.Node;
import it.uniroma1.dis.wsngroup.gexf4j.core.data.Attribute;
import it.uniroma1.dis.wsngroup.gexf4j.core.data.AttributeClass;
import it.uniroma1.dis.wsngroup.gexf4j.core.data.AttributeList;
import it.uniroma1.dis.wsngroup.gexf4j.core.data.AttributeType;
import it.uniroma1.dis.wsngroup.gexf4j.core.impl.GexfImpl;
import it.uniroma1.dis.wsngroup.gexf4j.core.impl.StaxGraphWriter;
import it.uniroma1.dis.wsngroup.gexf4j.core.impl.data.AttributeListImpl;
import u.can.i.up.db.postgresql.Aliases;
import u.can.i.up.utils.StringUtils;

public class AliasesGenerator {

	private final static AliasesGenerator instant = new AliasesGenerator();

	Logger logger = LogManager.getLogger(AliasesGenerator.class);

	public static AliasesGenerator getInstant() {
		return instant;
	}

	private final String AliasesFilePath = "/Users/lczgywzyy/Desktop/Aliases.gexf";

	public int addAliase(String aliasesFilePath, List<Aliases> aliases, Map<Integer, Float> map) {
		// 实例化
		Gexf gexf = new GexfImpl();
		// 日期
		Calendar date = Calendar.getInstance();
		// 初始化
		gexf.getMetadata().setLastModified(date.getTime()).setCreator("Gephi.org").setDescription("ICC CRSPR");
		gexf.setVisualization(true);

		Graph graph = gexf.getGraph();
		// 无向边
		graph.setDefaultEdgeType(EdgeType.DIRECTED).setMode(Mode.STATIC);
		// 添加节点字段
		AttributeList nodeAttrList = new AttributeListImpl(AttributeClass.NODE);
		graph.getAttributeLists().add(nodeAttrList);

		Attribute Ncomponent = nodeAttrList.createAttribute("Component", AttributeType.STRING, "component");
		Attribute Nkind = nodeAttrList.createAttribute("Kind", AttributeType.STRING, "kind");
		Attribute Napp = nodeAttrList.createAttribute("AppPackageName", AttributeType.STRING, "app");
		Attribute NCRSPR = nodeAttrList.createAttribute("CRSPR", AttributeType.FLOAT, "CRSPR");
		Attribute Nappcategoryid = nodeAttrList.createAttribute("CategoryID", AttributeType.INTEGER, "App_Category_ID");
		Attribute Nappcategory = nodeAttrList.createAttribute("Category", AttributeType.STRING, "App_Category");

		// 添加边字段
		// AttributeList edgeAttrList = new
		// AttributeListImpl(AttributeClass.EDGE);
		// graph.getAttributeLists().add(edgeAttrList);
		//
		// Attribute Ecomponent_source = edgeAttrList.createAttribute("0",
		// AttributeType.STRING, "source_component");
		// Attribute Ecomponent_target = edgeAttrList.createAttribute("1",
		// AttributeType.STRING, "target_component");

		for (int i = 0; i < aliases.size(); i++) {
			Aliases a = aliases.get(i);
			Node source = graph.createNode("" + a.getSid());
			source.setLabel(a.getScomponent()).getAttributeValues().addValue(Ncomponent, a.getScomponent())
					.addValue(Nkind, a.getSkind()).addValue(Napp, a.getSapp())
					.addValue(NCRSPR, "" + ((map.get(a.getSid()) != null) ? map.get(a.getSid()) : 0.0))
					.addValue(Nappcategoryid, "" + a.getScategoryid()).addValue(Nappcategory, "" + a.getScategory());
			Node target = graph.createNode("" + a.getTid());
			target.setLabel(a.getTcomponent()).getAttributeValues().addValue(Ncomponent, a.getTcomponent())
					.addValue(Nkind, a.getTkind()).addValue(Napp, a.getTapp())
					.addValue(NCRSPR, "" + ((map.get(a.getTid()) != null) ? map.get(a.getTid()) : 0.0))
					.addValue(Nappcategoryid, "" + a.getTcategoryid()).addValue(Nappcategory, "" + a.getTcategory());
			source.connectTo(a.getAliaseid().toString(), "", EdgeType.DIRECTED, target);
		}

		StaxGraphWriter graphWriter = new StaxGraphWriter();
		File f = new File(aliasesFilePath);
		Writer out;
		try {
			out = new FileWriter(f, false);
			graphWriter.writeToStream(gexf, out, "UTF-8");
			logger.info(f.getAbsolutePath());
		} catch (IOException e) {
			e.printStackTrace();
			return -1;
		}
		return 0;
	}

	public int addAliase(List<Aliases> aliases) {
		// 实例化
		Gexf gexf = new GexfImpl();
		// 日期
		Calendar date = Calendar.getInstance();
		// 初始化
		gexf.getMetadata().setLastModified(date.getTime()).setCreator("Gephi.org").setDescription("A Web network");
		gexf.setVisualization(true);

		Graph graph = gexf.getGraph();
		// 无向边
		graph.setDefaultEdgeType(EdgeType.DIRECTED).setMode(Mode.STATIC);
		// 添加节点字段
		AttributeList nodeAttrList = new AttributeListImpl(AttributeClass.NODE);
		graph.getAttributeLists().add(nodeAttrList);

		Attribute Ncomponent = nodeAttrList.createAttribute("0", AttributeType.STRING, "component");
		Attribute Nkind = nodeAttrList.createAttribute("1", AttributeType.STRING, "kind");
		Attribute Napp = nodeAttrList.createAttribute("2", AttributeType.STRING, "app");

		// 添加边字段
		// AttributeList edgeAttrList = new
		// AttributeListImpl(AttributeClass.EDGE);
		// graph.getAttributeLists().add(edgeAttrList);
		//
		// Attribute Ecomponent_source = edgeAttrList.createAttribute("0",
		// AttributeType.STRING, "source_component");
		// Attribute Ecomponent_target = edgeAttrList.createAttribute("1",
		// AttributeType.STRING, "target_component");

		for (int i = 0; i < aliases.size(); i++) {
			Aliases a = aliases.get(i);
			Node source = graph.createNode("" + a.getSid());
			source.setLabel(a.getScomponent()).getAttributeValues().addValue(Ncomponent, a.getScomponent())
					.addValue(Nkind, a.getSkind()).addValue(Napp, a.getSapp());
			Node target = graph.createNode("" + a.getTid());
			target.setLabel(a.getTcomponent()).getAttributeValues().addValue(Ncomponent, a.getTcomponent())
					.addValue(Nkind, a.getTkind()).addValue(Napp, a.getTapp());
			source.connectTo(a.getAliaseid().toString(), "", EdgeType.DIRECTED, target);
			// .getAttributeValues()
			// .addValue(Ecomponent_source, a.getScomponent())
			// .addValue(Ecomponent_target, a.getTcomponent());
		}

		StaxGraphWriter graphWriter = new StaxGraphWriter();
		File f = new File(AliasesFilePath);
		Writer out;
		try {
			out = new FileWriter(f, false);
			graphWriter.writeToStream(gexf, out, "UTF-8");
			logger.info(f.getAbsolutePath());
		} catch (IOException e) {
			e.printStackTrace();
			return -1;
		}
		return 0;
	}

	public int addAliase(String AliasesFilePath, List<Aliases> aliases) {
		// 实例化
		Gexf gexf = new GexfImpl();
		// 日期
		Calendar date = Calendar.getInstance();
		// 初始化
		gexf.getMetadata().setLastModified(date.getTime()).setCreator("Gephi.org").setDescription("A Web network");
		gexf.setVisualization(true);

		Graph graph = gexf.getGraph();
		// 无向边
		graph.setDefaultEdgeType(EdgeType.DIRECTED).setMode(Mode.STATIC);
		// 添加节点字段
		AttributeList nodeAttrList = new AttributeListImpl(AttributeClass.NODE);
		graph.getAttributeLists().add(nodeAttrList);

		Attribute Ncomponent = nodeAttrList.createAttribute("0", AttributeType.STRING, "component");
		Attribute Nkind = nodeAttrList.createAttribute("1", AttributeType.STRING, "kind");
		Attribute Napp = nodeAttrList.createAttribute("2", AttributeType.STRING, "app");

		for (int i = 0; i < aliases.size(); i++) {
			Aliases a = aliases.get(i);
			Node source = graph.createNode("" + a.getSid());
			source.setLabel(a.getScomponent()).getAttributeValues().addValue(Ncomponent, a.getScomponent())
					.addValue(Nkind, a.getSkind()).addValue(Napp, a.getSapp());
			Node target = graph.createNode("" + a.getTid());
			target.setLabel(a.getTcomponent()).getAttributeValues().addValue(Ncomponent, a.getTcomponent())
					.addValue(Nkind, a.getTkind()).addValue(Napp, a.getTapp());
			source.connectTo(a.getAliaseid().toString(), "", EdgeType.DIRECTED, target);
		}

		StaxGraphWriter graphWriter = new StaxGraphWriter();
		File f = new File(AliasesFilePath);
		Writer out;
		try {
			out = new FileWriter(f, false);
			graphWriter.writeToStream(gexf, out, "UTF-8");
			logger.info(f.getAbsolutePath());
		} catch (IOException e) {
			e.printStackTrace();
			return -1;
		}
		return 0;
	}

	public int addAliaseByThirdPartyList(String AliasesFilePath, List<Aliases> aliases,
			Map<String, Integer> ThirdPartyMap) {
		// 实例化
		Gexf gexf = new GexfImpl();
		// 日期
		Calendar date = Calendar.getInstance();
		// 初始化
		gexf.getMetadata().setLastModified(date.getTime()).setCreator("Gephi.org").setDescription("A Web network");
		gexf.setVisualization(true);

		Graph graph = gexf.getGraph();
		// 无向边
		graph.setDefaultEdgeType(EdgeType.DIRECTED).setMode(Mode.STATIC);
		// 添加节点字段
		AttributeList nodeAttrList = new AttributeListImpl(AttributeClass.NODE);
		graph.getAttributeLists().add(nodeAttrList);

		Attribute Ncomponent = nodeAttrList.createAttribute("0", AttributeType.STRING, "component");
		Attribute Nkind = nodeAttrList.createAttribute("1", AttributeType.STRING, "kind");
		Attribute Napp = nodeAttrList.createAttribute("2", AttributeType.STRING, "app");
		Attribute NThirdParty = nodeAttrList.createAttribute("3", AttributeType.BOOLEAN, "isThirdParty");

		for (int i = 0; i < aliases.size(); i++) {
			Aliases a = aliases.get(i);
			Node source = graph.createNode("" + a.getSid());
			source.setLabel(a.getScomponent()).getAttributeValues().addValue(Ncomponent, a.getScomponent())
					.addValue(Nkind, a.getSkind()).addValue(Napp, a.getSapp());
			String sourceComponent = a.getScomponent();
			if (sourceComponent != null && !sourceComponent.equals("")) {
				String sourcePkg = (sourceComponent.contains(".")) ? (StringUtils.splitPartStr(sourceComponent, ".", 3))
						: (sourceComponent);
				if (ThirdPartyMap.get(sourcePkg) == null) {
					source.getAttributeValues().addValue(NThirdParty, "False");
				} else {
					source.getAttributeValues().addValue(NThirdParty, "True");
				}
			}
			Node target = graph.createNode("" + a.getTid());
			target.setLabel(a.getTcomponent()).getAttributeValues().addValue(Ncomponent, a.getTcomponent())
					.addValue(Nkind, a.getTkind()).addValue(Napp, a.getTapp());
			String targetComponent = a.getTcomponent();
			if (targetComponent != null && !targetComponent.equals("")) {
				String targetPkg = (targetComponent.contains(".")) ? (StringUtils.splitPartStr(targetComponent, ".", 3))
						: (targetComponent);
				if (ThirdPartyMap.get(targetPkg) == null) {
					target.getAttributeValues().addValue(NThirdParty, "False");
				} else {
					target.getAttributeValues().addValue(NThirdParty, "True");
				}
			}
			source.connectTo(a.getAliaseid().toString(), "", EdgeType.DIRECTED, target);
		}

		StaxGraphWriter graphWriter = new StaxGraphWriter();
		File f = new File(AliasesFilePath);
		Writer out;
		try {
			out = new FileWriter(f, false);
			graphWriter.writeToStream(gexf, out, "UTF-8");
			logger.info(f.getAbsolutePath());
		} catch (IOException e) {
			e.printStackTrace();
			return -1;
		}
		return 0;
	}

}
